/* 
 *  Copyright (c) 2011—2013 Panguso.com. All rights reserved. 
 *  File Name:  CalculateTree.java                                      
 *  File Contents Outline :  计算过滤规则树                  
 *  File  Create Date:   2012年7月30日
 *  File Version#: Revision#: #1                  
 *  File  Latest Modify Date : 2013年1月16日
 *  File Author :  bachuan@panguso.com
 */

/*

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.edu.thu.log.tree;

import cn.edu.thu.log.filter.logfilter.ReadContentByTagName;
import cn.edu.thu.log.filter.parameter.FilterParameter;
import cn.edu.thu.log.read.LogBuffer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.edu.thu.log.web.service.PropertiesReaderServices;
import cn.edu.thu.log.web.service.impl.PropertiesReaderServicesImpl;
import storage.dbhelper.TreeFileHelper;

/**
 *
 * @author wan
 */
public class CalculateTree {

    private Map<ManyTreeNode, Boolean> resultMap;
    private ReadContentByTagName readcontent;
    private ArrayList<String> classifyTagList;
//    private ArrayList<String> headtagList;
//    private Map<String, String> bodytagMap;
//    private LogBuffer record;
//    private ArrayList<Boolean> resultList;
//    private Map<ManyTreeNode,ArrayList> resultMap;

    public CalculateTree(String classifyTags) {


        classifyTagList = new ArrayList<String>();
        System.out.println("classfifyTags 123:"+classifyTags);
        readcontent = new ReadContentByTagName();
        //如果设置了分段的tag，则设置分段的字段列表
        if (!classifyTags.equals("")) {
            String[] classifyArray = classifyTags.split(",");
            for (int i = 0; i < classifyArray.length; i++) {
                classifyTagList.add(classifyArray[i]);
            }
            readcontent.setClassifyTagList(classifyTagList);
        }
    }

    public boolean calculateTree(ManyTreeNode node, LogBuffer record) throws IOException {
//        System.out.println("\nIn the calculateTree method!");
//        System.out.println("当前计算节点是：" + node.getData().getNodename());

        ArrayList<ManyTreeNode> childList = node.getChildList();
        ArrayList<Boolean> resultList = new ArrayList<Boolean>();
        resultMap = new HashMap<ManyTreeNode, Boolean>();
        boolean basicOper, result = false;
//        System.out.println("当前计算节点的子节点列表");
//        for (Iterator<ManyTreeNode> it = childList.iterator(); it.hasNext();) {
//            ManyTreeNode chil = it.next();
//            if(chil.getData().getType().equals("tag format0")){
//                System.out.println("子节点类型："+chil.getData().getType()+" 子节点值："+chil.getData().getValue());
//            }
//            else if(chil.getData().getType().equals("tag format1")){
//                 System.out.println("子节点类型："+chil.getData().getType()+" 子节点值："+chil.getData().getValueList());
//            }
//            else{
//                System.out.println("子节点类型："+chil.getData().getType()+" 子节点值："+chil.getData().getNodename());
//            }
//        }
        int flag = 0;//一个i节点的所有子孩子结果是否全部得出，如果得出为0，否则为1

        // 1、无孩子，错误的结果
        if (childList.isEmpty()) {
            return false;
        }

        basicOper = true;
        for (ManyTreeNode childnode : childList) {
            if (!childnode.getChildList().isEmpty()) {
                basicOper = false;
            }
        }

        // 2、如果是基本操作符 smaller equal等
        if (basicOper) {
         //   System.out.print("BASIC OPER.\t");
            result = calculateOperator(node, record);
            return result;
        }

        // 3、如果是高级操作符and or not等
        for (ManyTreeNode childnode : childList) {
            flag++;
            resultList.add(calculateTree(childnode, record));
        }

        if (flag == childList.size()) {
         //   System.out.println("\n孩子节点的值全部算出，计算当前节点值");
          //  System.out.println("resultList的值" + resultList);
            result = calculateOperator(node, resultList);
            return result;
        }

        return result;
    }

    /**
     * 对高级操作符的运算
     */
    private boolean calculateOperator(ManyTreeNode node, ArrayList<Boolean> list) {
//        System.out.println("\n在计算一级操作符的方法中");
        String nodetype = node.getData().getType();
//        System.out.println("current first operator type is:"+nodetype);
//        System.out.println("此操作符的孩子结果列表是："+list);
//        for(Boolean boolvalue:list){
//            System.out.print(boolvalue+" ");
//        }        
        if (nodetype.equals("operator")) {
            String operator = node.getData().getNodename();
//            System.out.println("current first operator is:"+operator);
            //对and的计算
            if (operator.equals(FilterParameter.OPERATOR_AND)) {
                System.out.println("and计算");
                for (Boolean bool : list) {
//                    System.out.println("bool值"+bool);
                    if (bool == true) {
                        return true;
                    }
                }
                return false;
            }
            //对or的计算
            if (operator.equals(FilterParameter.OPERATOR_OR)) {
//                System.out.println("or计算");
                for (Boolean bool : list) {
                    if (bool == false) {
                        return false;
                    }
                }
                return true;
            }
            //对not的计算
            if (operator.equals(FilterParameter.OPERATOR_NOT)) {
//                System.out.println("not计算");
                return !list.get(0);
            }
        }
        System.out.println("规则错误！");
        return true;

    }

    /**
     * 对二级操作符的计算
     *
     * @param node
     * @param record
     * @return
     */
    private boolean calculateOperator(ManyTreeNode node, LogBuffer record) throws IOException {
        // 是噪音返回true，否则返回false
//       System.out.println("在计算二级操作符的方法中");
//        System.out.println("current node type is:" + node.getData().getType());
        ArrayList<ManyTreeNode> childList = node.getChildList();
        String operator = node.getData().getNodename();
  //      System.out.println("current operator is: " + operator);

        String tagname = "";//字段名称
        String tagvalue = "";//字段内容
        String formatvalue = "";//字段格式（单串）
        String[] valueList = null;//字段格式（列表）
        ArrayList<String> valueArray = new ArrayList<String>();

        for (ManyTreeNode cnode : childList) {
            String type = cnode.getData().getType();
            if (type.equals(XMLNode.TAGNAME)) {
                tagname = cnode.getData().getNodename();
                tagvalue = readcontent.getAndCutContentByTagName(tagname, record);
            }
            if (type.equals(XMLNode.TAGFORMAT + "0")) {
                formatvalue = cnode.getData().getValue();
            }
            if (type.equals(XMLNode.TAGFORMAT + "1")) {
                if (cnode.getData().getValueList() == null) {
                    valueList = null;
                } else if (cnode.getData().getValueList()[0].startsWith("LIST_")) {
                    String listFileName = cnode.getData().getValueList()[0].substring("LIST_".length());
//                    cnode.getData().setValueList(readStatisticsTXT(listFileName));
                    cnode.getData().setValueList(readCassandraTXT(listFileName));
                } else {
                    valueList = cnode.getData().getValueList();
                    for (int i = 0; i < valueList.length; i++) {
                        valueArray.add(valueList[i]);
                    }
//                    System.out.println("valueArray:"+valueArray);
                }
            }
        }

        /*
         * 排除没有对应字段的产品，直接返回,是噪音，除Referer之外
         */
//        System.out.println("tagvalue:\t" + tagvalue);
        if ((tagvalue == null || tagvalue.equals("")) && !tagname.equals("Referer")) {
            return true;
        }

        //小于
        if (operator.equals(FilterParameter.OPERATOR_SMALLER)) {
            if (Integer.parseInt(tagvalue) < Integer.parseInt(formatvalue)) {
//                System.out.println();
                return false;
            } else {
                return true;
            }
        }
        //大于
        if (operator.equals(FilterParameter.OPERATOR_BIGGER)) {
            if (Integer.parseInt(tagvalue) > Integer.parseInt(formatvalue)) {
                return false;
            } else {
                return true;
            }
        }
        //不大于
        if (operator.equals(FilterParameter.OPERATOR_NOT_BIGGER)) {
            if (Integer.parseInt(tagvalue) <= Integer.parseInt(formatvalue)) {
                return false;
            } else {
                return true;
            }
        }
        //不小于
        if (operator.equals(FilterParameter.OPERATOR_NOT_SMALLER)) {
//            System.out.println("当前操作符：not smaller");
            if (Integer.parseInt(tagvalue) >= Integer.parseInt(formatvalue)) {
                return false;
            } else {
                return true;
            }
        }
        //在....之间
        if (operator.equals(FilterParameter.OPERATOR_BETWEEN)) {

            String substr = formatvalue.substring(1, formatvalue.length() - 1);
            String[] bvaluelist = substr.split(",");
            double from = Double.parseDouble(bvaluelist[0]);
            double to = Double.parseDouble(bvaluelist[1]);
            double value= Double.parseDouble(tagvalue);
            if ((from<=value)&&(value<=to)) {
                return true;
            } else {
                return false;
            }

            /*if (bvaluelist[0].compareTo(tagvalue) < 0
                    && tagvalue.compareTo(bvaluelist[1]) < 0) {
                return false;
            } else if (bvaluelist[1].compareTo(tagvalue) < 0
                    && tagvalue.compareTo(bvaluelist[0]) < 0) {
                return false;
            } else {
                return true;
            }*/

        }
        //不在...之间
        if (operator.equals(FilterParameter.OPERATOR_NOT_BETWEEN)) {

            String substr = formatvalue.substring(1, formatvalue.length() - 1);
            String[] nbvaluelist = substr.split(",");


            if (tagvalue.compareTo(nbvaluelist[0]) < 0
                    && nbvaluelist[0].compareTo(nbvaluelist[1]) <= 0) {
                return false;
            } else if (nbvaluelist[0].compareTo(nbvaluelist[1]) <= 0
                    && nbvaluelist[1].compareTo(tagvalue) < 0) {
                return false;
            } else {
                return true;
            }

        }
        // 时间区间（不包含年月日）
        if (operator.equals(FilterParameter.OPERATOR_DURATION)) {

            String substr = formatvalue.substring(1, formatvalue.length() - 1);
            String[] valuelist = substr.split(",");
            String timeValue = tagvalue.substring(8);

            if (valuelist[0].compareTo(timeValue) < 0
                    && timeValue.compareTo(valuelist[1]) < 0) {
                return false;
            }

            return true;
        }
        // 等于
        if (operator.equals(FilterParameter.OPERATOR_EQUAL)) {
            System.out.println("获取的值:" + tagvalue + " 要求值为：" + formatvalue);
            return !(tagvalue.compareTo(formatvalue) == 0);
        }

        // 不等于
        if (operator.equals(FilterParameter.OPERATOR_NOT_EQUAL)) {
            return tagvalue.compareTo(formatvalue) == 0;
        }

        //等于（忽略大小写）
        if (operator.equals(FilterParameter.OPERATOR_EQUAL_WITHOUT_CASE)) {
//             System.out.println("当前操作符：equal without case");
            return !(tagvalue.compareToIgnoreCase(formatvalue) == 0);
        }

        //不等于（忽略大小写)
        if (operator.equals(FilterParameter.OPERATOR_NOT_EQUAL_WITHOUT_CASE)) {
//             System.out.println("当前操作符：not eaqual without case");
            return tagvalue.compareToIgnoreCase(formatvalue) == 0;
        }

        //存在与某个列表中，如果存在于其中一个值中，则返回true
        if (operator.equals(FilterParameter.OPERATOR_IN)) {
//            System.out.println("当前操作符：in");
//                System.out.println("值是："+tagvalue);
//                System.out.println("valueArray:"+valueArray);
            return !valueArray.contains(tagvalue);

        }

        //不存在于某个列表中,如果存在其中任何一个，则返回false
        if (operator.equals(FilterParameter.OPERATOR_NOT_IN)) {
//             System.out.println("当前操作符：not in");
            return valueArray.contains(tagvalue);
        }

        //存在与某个子串列表，值是一个列表
        if (operator.equals(FilterParameter.OPERATOR_LIKE)) {
//             System.out.println("当前操作符：like");
            Pattern pattern = null;
            Matcher matcher = null;
            int flag = 0;//默认不存在于此列表
            for (String va : valueArray) {
                pattern = Pattern.compile(va);
                matcher = pattern.matcher(tagvalue);
                if (matcher.matches()) {
//                System.out.println("出现不符合情况的字段" + tagname + "的内容 " + tagvalue + "不符合规则"
//                        + formatvalue);
                    flag = 1;
                }
            }
            //没有出现存在于列表中的子串
            if (flag == 0) {
                return true;
            } else {
                return false;
            }
        }

        //不存在某个子串,值是一个列表值
        if (operator.equals(FilterParameter.OPERATOR_NOT_LIKE)) {
            Pattern pattern = null;
            Matcher matcher = null;
//             System.out.println("当前操作符：not like");
            for (String va : valueArray) {
                pattern = Pattern.compile(va);
                matcher = pattern.matcher(tagvalue);

                // 如果匹配，则表示出现了不应该存在的子串
                if (matcher.matches()) {
//                    System.out.println("字段值:" + tagvalue + "\t目标值:" + va + "\t匹配");
//                    System.out.println("结果为true\n");
                    return true;
                }
//                System.out.println("字段值:" + tagvalue + "\t目标值:" + va + "\t不匹配");
            }
//            System.out.println("结果为false\n");
            return false;
        } else {
            return false;
        }
    }

    private String[] readStatisticsTXT(String filename) throws IOException {
        PropertiesReaderServices x1 = PropertiesReaderServicesImpl.instance();
        BufferedReader br = new BufferedReader(new FileReader(x1.getProperties("uploadCSVAnalysePath") + filename));
        System.out.println("readfile:" + filename);
        ArrayList<String> temp = new ArrayList<String>();
        String r = br.readLine();
        while (r != null) {
            temp.add(r);
            r = br.readLine();
        }
        String[] list = new String[temp.size()];
        for (int i = 0; i < temp.size(); i++) {
            list[i] = temp.get(i);
        }
        return list;
    }

    private String[] readCassandraTXT(String filename){
        TreeFileHelper ph = new TreeFileHelper();
        String s = ph.selectTreeFile(filename);
        System.out.println(s);
        String[] list = s.split("\n");
        System.out.println(list.length);
        for (String ss : list) {
            System.out.println(ss);
        }
        return list;
    }

    public static void main(String[] args) {
        CalculateTree ct = new CalculateTree("");
        ct.readCassandraTXT("23115289657263.txt");
    }
}
